package comcksys.authserver.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.util.TypeUtils;
import comcksys.authserver.config.convert.Oauth2AuthenticationSerializer;
import comcksys.authserver.util.RedisUtil;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
import org.springframework.security.oauth2.provider.code.RandomValueAuthorizationCodeServices;

/**
 * 授权码保存(采用Redis保存)
 * @author: yxzhang23
 * @time: 2021/4/13
 */
public class RandomValueAuthorizationCodeServicesImpl extends RandomValueAuthorizationCodeServices {

    private final RedisUtil redisUtil;

    private static final ParserConfig PARSER_CONFIG = new ParserConfig();

    static {
        PARSER_CONFIG.putDeserializer(OAuth2Authentication.class, new Oauth2AuthenticationSerializer());
        PARSER_CONFIG.addAccept("org.springframework.security.oauth2.provider.");
        PARSER_CONFIG.addAccept("org.springframework.security.oauth2.provider.client");
        TypeUtils.addMapping("org.springframework.security.oauth2.provider.OAuth2Authentication",
                OAuth2Authentication.class);
        TypeUtils.addMapping("org.springframework.security.oauth2.provider.client.BaseClientDetails",
                BaseClientDetails.class);
    }

    public RandomValueAuthorizationCodeServicesImpl(RedisUtil redisUtil) {
        this.redisUtil = redisUtil;

    }

    /**
     * 存储授权码和用户权限信息
     * @param code  授权码
     * @param oAuth2Authentication  用户权限信息
     */
    @Override
    protected void store(String code, OAuth2Authentication oAuth2Authentication) {
        String oauth2 = JSON.toJSONString(oAuth2Authentication, SerializerFeature.WriteClassName,
                SerializerFeature.DisableCircularReferenceDetect);
        redisUtil.set(code, oauth2);
    }

    /**
     * 移除授权码和用户权限信息
     * 暂时在获取之后进行移除
     * @param code  授权码
     * @return      用户权限信息
     */
    @Override
    protected OAuth2Authentication remove(String code) {
        OAuth2Authentication oAuth2Authentication = JSON.parseObject((String) redisUtil.get(code),
                OAuth2Authentication.class, PARSER_CONFIG);
        redisUtil.del(code);
        return oAuth2Authentication;
    }
}
